package com.yuanian.wf.pojo.dto;

import com.yuanian.wf.context.spring.ApplicationContext;
import com.yuanian.wf.utils.ActivitiUtils;
import de.odysseus.el.util.SimpleContext;
import org.activiti.bpmn.model.*;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.task.Task;
import org.apache.el.ExpressionFactoryImpl;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import java.util.List;
import java.util.Map;

public class CompleteTaskDto<T> extends BaseDto {

    //任务ID
    private String taskId;
    //当前的任务
    private Task task;
    //当前任务详情
    private UserTask userTask;
    //完成后的新任务
    private Task nextTask;
    //完成后的新任务详情
    private UserTask nextUserTask;
    //下一步是否为结束
    private boolean nextIsEnd;

    public String getTaskId() {
        return taskId;
    }

    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }

    public Task getTask() {
        return task;
    }

    public void initTask(Task task) {
        this.task = task;
        initTask();
    }

    public Task getNextTask() {
        return nextTask;
    }

    public void setNextTask(Task nextTask) {
        this.nextTask = nextTask;
    }

    public UserTask getUserTask() {
        return userTask;
    }

    public void setUserTask(UserTask userTask) {
        this.userTask = userTask;
    }

    public UserTask getNextUserTask() {
        return nextUserTask;
    }

    public void setNextUserTask(UserTask nextUserTask) {
        this.nextUserTask = nextUserTask;
    }

    public boolean nextIsEnd() {
        return nextIsEnd;
    }
    /**
     * 下一步是否结束
     * @return
     */
    public void initTask() {
        //获取流程定义的模板
        BpmnModel model = ApplicationContext.getBean(RepositoryService.class).getBpmnModel(getTask().getProcessDefinitionId());
        this.processKey = model.getMainProcess().getId();
        //获取当前任务节点的元素
        FlowElement flowElement = model.getFlowElement(getTask().getTaskDefinitionKey());
        if (flowElement instanceof UserTask) {
            UserTask userTask = (UserTask)flowElement;
            this.setUserTask(userTask);
            //获取当前节点的出线
            List<SequenceFlow> sequenceFlowList = userTask.getOutgoingFlows();
            UserTask nextUserTask = ActivitiUtils.findFirstUserTask(sequenceFlowList, variables);
            this.setNextUserTask(nextUserTask);
            //没有下一个任务
            if (nextUserTask == null) {
                this.nextIsEnd = true;
            }
        }
    }

    private void parseNextTask(List<SequenceFlow> sequenceFlows, Map<String, Object> variables) {
        for (SequenceFlow sequenceFlow : sequenceFlows) {
            //无条件的执行
            String exp = sequenceFlow.getConditionExpression();
            if (exp == null || isCondition(exp, variables)) {
                FlowElement flowElement = sequenceFlow.getTargetFlowElement();
                if (flowElement instanceof UserTask) {
                    this.setNextUserTask((UserTask)flowElement);
                    break;
                } else if (flowElement instanceof ExclusiveGateway) {//排他网关
                    ExclusiveGateway exclusiveGateway = (ExclusiveGateway)flowElement;
                    parseNextTask(exclusiveGateway.getOutgoingFlows(), variables);
                } else if (flowElement instanceof EndEvent) {
                    nextIsEnd = true;
                    break;
                }
            }
        }
    }


    private boolean isCondition(String el, Map<String, Object> variables) {
        ExpressionFactory factory = new ExpressionFactoryImpl();
        SimpleContext context = new SimpleContext();
        variables.forEach((key, value) -> {
            context.setVariable(key, factory.createValueExpression(value, String.class));
        });
        ValueExpression e = factory.createValueExpression(context, el, boolean.class);
        return (Boolean) e.getValue(context);
    }

}
